import { Graph, treeToGraphData, NodeEvent, GraphEvent } from '@antv/g6'
import type { Graph as GraphType } from '@antv/g6'
import graphBackgroundImage from '@/assets/imgs/teachingMap.png'
import { getViewportPx } from '@/utils/formatter'
import { eachTree } from '@/utils/tree'

// 将后端返回的数据转换为前端需要的格式
const transformNodeData = (node: any): any => {
  return {
    id: node.id?.toString(),
    label: node.name,
    description: node.description,
    keyFeatures: node.keyFeatures || [],
    tags: node.tags || [],
    learningUnits: [], // 学习单元将在NodeDetailDrawer中通过API获取
    learningResources: [], // 学习资源将在NodeDetailDrawer中通过API获取
    children: node.children ? node.children.map(transformNodeData) : [],
    resourceCount: node.resourceCount // 用于展示学习单元和资源数量
  }
}

export const G6Config = ({ init, onNodeClick, onRendered }) => {
  let graph: GraphType | null = null
  const graphContainer: any = ref(null)

  onMounted(() => {
    nextTick(() => {
      if (graphContainer.value) {
        initGraph()
      }
    })
  })

  onUnmounted(() => {
    if (graph) {
      graph.destroy()
      graph = null
    }
  })

  async function initGraph() {
    if (!graphContainer.value) return

    // 获取数据
    const treeData = await init?.()
    if (!treeData) {
      return
    }
    const transformedData = transformNodeData(treeData)
    const centerNodeId = transformedData.id
    eachTree([transformedData], (element, parentNode) => {
      if (parentNode.id) {
        element.parentNode = {
          id: parentNode.id,
          label: parentNode.label
        }
      }
    })

    const graphData = treeToGraphData(transformedData)
    // 计算每个节点的子节点数量
    const childrenCount: Record<string, number> = {}
    graphData.edges?.forEach((edge) => {
      if (edge.source) {
        childrenCount[edge.source] = (childrenCount[edge.source] || 0) + 1
      }
    })
    const { width: graphWidth, height: graphHeight } = graphContainer.value.getBoundingClientRect()
    // 创建图实例
    graph = new Graph({
      container: graphContainer.value,
      autoFit: 'center',
      data: graphData,
      theme: 'light',
      autoResize: true,
      x: graphWidth / 2,
      y: graphHeight / 2,
      zoomRange: [0.5, 7],
      zoom: 1.1,
      node: {
        type: 'circle',
        style: (d: any) => {
          // 根据节点层级设置不同大小
          const depth: number = (d?.depth as number) || (d?.data?.depth as number) || 0
          let size, fill, stroke, badges

          if (depth === 0) {
            size = 80 // 根节点最大
            fill = 'l(0) 0:#6E81FF 1:#BC9EFF' // 渐变色
            stroke = 'l(0) 0:rgba(110, 129, 255, 0.1) 1:rgba(188, 158, 255, 0.1)'
          } else if (depth === 1) {
            size = 60 // 一级子节点
            fill = 'l(0) 0:#6E81FF 1:#BC9EFF' // 渐变色
            stroke = 'l(0) 0:rgba(110, 129, 255, 0.1) 1:rgba(188, 158, 255, 0.1)'
          } else {
            size = 30 // 其他节点
            fill = 'l(0) 0:#6E81FF 1:#BC9EFF' // 渐变色
            stroke = 'l(0) 0:rgba(110, 129, 255, 0.1) 1:rgba(188, 158, 255, 0.1)'
            // 使用resourceCount替代learningUnits.length
            if (d?.resourceCount) {
              badges = [
                {
                  text: d.resourceCount.toString(),
                  placement: 'top',
                  backgroundFill: '#FF4D4F', // 红色背景
                  fill: '#fff', // 白色文字
                  fontSize: 12,
                  background: false,
                  offsetY: 8
                }
              ]
            }
          }

          return {
            size,
            fill,
            stroke,
            badges,
            lineWidth: 12, // 增大边缘过渡区域
            lineDash: [0, 0],
            shadowColor: 'transparent',
            shadowBlur: 0,
            shadowOffsetX: 0,
            shadowOffsetY: 0,
            fillOpacity: 0.9,
            labelFill: depth < 2 ? '#fff' : '#333',
            labelFontSize: depth < 1 ? 14 : 12, // 继续缩小一级二级节点字体
            labelText: (d?.label as string) || (d?.data?.label as string) || (d?.id as string),
            labelPlacement: depth <= 1 ? 'center' : 'bottom',
            labelWordWrap: true,
            // labelLineHeight: depth < 1 ? 14 : 12,
            // labelTextBaseline: 'middle',
            labelMaxWidth: depth <= 1 ? size - 15 : 100,
            // labelPadding: [25, 15, 15, 15],
            labelMaxLines: depth <= 1 ? 2 : 1,
            labelTextOverflow: 'ellipsis',
            labelFillOpacity: 1,
            labelOffsetY: depth !== 1 ? 5 : 3, // 三级节点文字与节点间距
            halo: false
          }
        },
        state: {
          hover: {
            cursor: 'pointer',
            halo: true,
            haloStroke: 'l(0) 0:rgba(110, 129, 255, 0.8) 1:rgba(188, 158, 255, 0.8)',
            haloLineWidth: 20,
            haloStrokeOpacity: 0.9,
            lineWidth: 8, // hover时边缘更明显
            stroke: 'l(0) 0:rgba(110, 129, 255, 1) 1:rgba(188, 158, 255, 1)',
            shadowColor: 'rgba(110, 129, 255, 0.8)',
            shadowBlur: 20,
            shadowOffsetX: 0,
            shadowOffsetY: 0
          },
          active: {
            lineWidth: 8,
            stroke: 'l(0) 0:rgba(110, 129, 255, 1) 1:rgba(188, 158, 255, 1)'
          }
        },
        animation: {
          enter: false, // 禁用进入动画减少抖动
          update: false // 禁用更新动画减少抖动
        }
      },
      edge: {
        type: 'quadratic',
        style: {
          stroke: 'l(0) 0:rgba(110, 129, 255, 0.4) 1:rgba(188, 158, 255, 0.4)',
          lineWidth: 1.5,
          endArrow: true,
          endArrowType: 'circle', // 箭头改为圆点
          endArrowSize: 4,
          strokeOpacity: 0.4, // 淡化连线
          shadowColor: 'transparent',
          shadowBlur: 0
        },
        state: {
          hover: {
            stroke: 'l(0) 0:#6E81FF 1:#BC9EFF',
            lineWidth: 2,
            strokeOpacity: 0.9
          }
        }
      },
      layout: {
        type: 'd3-force',
        preventOverlap: true,
        // preLayout: true,
        nodeSize: (d) => {
          const depth: number = (d?.depth as number) || (d?.data?.depth as number) || 0
          if (depth === 0) return 80
          if (depth === 1) return 60
          return 30
        },
        link: {
          distance: (d) => {
            // 根据连接的节点层级和子节点数量动态设置边长
            const sourceDepth = (d.source as any)?.depth || (d.source as any)?.data?.depth || 0
            const targetDepth = (d.target as any)?.depth || (d.target as any)?.data?.depth || 0

            // 如果是根节点到一级节点，根据一级节点的子节点数量动态调整距离
            if (sourceDepth === 0 && targetDepth === 1) {
              const targetId = (d.target as any)?.id || (d.target as any)?.data?.id
              const childCount = childrenCount[targetId] || 0
              const num = childCount < 5 ? 15 : 25
              // 子节点越多，一级节点离根节点越远
              return 80 + Math.min(childCount * num, 400)
            }

            // 如果是一级节点到二级节点，根据二级节点的子节点数量调整距离
            if (sourceDepth === 1 && targetDepth === 2) {
              const targetId = (d.target as any)?.id || (d.target as any)?.data?.id
              const childCount = childrenCount[targetId] || 0
              return 130 + Math.min(childCount * 25, 250)
            }

            // 其他情况使用默认距离
            return 100
          },
          strength: 1
        },
        manyBody: {
          strength: (d) => {
            const depth: number = (d?.depth as number) || (d?.data?.depth as number) || 0
            if (depth === 1) {
              return -1200
            }
            return -500
          }
          // distanceMin: 80,
          // distanceMax: 800
        },
        collide: {
          radius: (d) => {
            const depth: number = (d?.depth as number) || (d?.data?.depth as number) || 0
            if (depth === 0) return 60
            if (depth === 1) return 70
            return 60
          },
          strength: 1.2,
          iterations: 1
        },
        center: {
          x: 0,
          y: 0,
          strength: 0.4
        },
        alpha: 1,
        alphaMin: 0.09,
        alphaDecay: 0.04,
        velocityDecay: 0.2,
        iterations: 2
      },
      behaviors: [
        'drag-canvas',
        {
          type: 'zoom-canvas',
          sensitivity: 0.6 // 降低灵敏度，缩放变化更平缓
        },
        {
          type: 'hover-activate',
          degree: 2
        }
      ],
      plugins: [
        {
          type: 'background',
          key: 'graph-background', // 为插件指定标识符，方便动态更新
          width: '100%',
          height: '100%',
          backgroundPosition: 'center 12px', // 设置背景位置居中
          backgroundRepeat: 'no-repeat', // 防止背景重复
          backgroundSize: getViewportPx(704), // 背景图片覆盖整个容器
          backgroundImage: `url(${graphBackgroundImage})` // 设置背景图
        },
        {
          type: 'tooltip',
          enable: (e) => e.targetType === 'node',
          getContent: (e: any, items: any) => {
            const item = items[0]
            if (e.targetType === 'node') {
              return `
                <div style="padding: 0px;">
                  <h4 style="margin: 0 0 4px; color: #6E81FF;">${item.label || item.data?.label || item.id}</h4>
                  <div style="color: #666; font-size: 12px;
                  overflow: hidden;
                  text-overflow: ellipsis;
                  display: -webkit-box;
                  -webkit-line-clamp: 2;
                  overflow:hidden;
                  -webkit-box-orient: vertical;">
                    ${item.description || item.data?.description || '暂无描述'}
                  </div>
                </div>
              `
            }
            // else if (e.targetType === 'edge') {
            //   return `
            //     <div style="padding: 8px;">
            //       <h4 style="margin: 0 0 4px; color: #6E81FF;">关系</h4>
            //       <div style="color: #666; font-size: 12px;">
            //         ${item.label || item.data?.label || '无标签'}
            //       </div>
            //     </div>
            //   `
            // }
            return ''
          },
          enterable: true,
          offset: [10, 10]
        },
        {
          type: 'toolbar',
          position: 'right-top',
          onClick: async (value: string) => {
            if (!graph) return
            switch (value) {
              case 'zoom-in':
                graph.zoomBy(1.2)
                break
              case 'zoom-out':
                graph.zoomBy(0.8)
                break
              case 'reset':
                await graph?.zoomTo(1.1, true, graph?.getCanvasCenter())
                graph?.focusElement(centerNodeId)
                break
              case 'auto-fit':
                graph.fitView()
                break
            }
          },
          getItems: () => [
            { id: 'zoom-in', value: 'zoom-in' },
            { id: 'zoom-out', value: 'zoom-out' },
            { id: 'reset', value: 'reset' },
            { id: 'auto-fit', value: 'auto-fit' }
          ]
        },
        {
          type: 'minimap',
          size: [200, 130],
          position: 'right-bottom',
          containerStyle: {
            opacity: 1
          }
        }
      ]
    })

    // 绑定节点点击事件
    graph.on(NodeEvent.CLICK, (e: any) => {
      const { target } = e
      const nodeData = graph?.getNodeData(target.id)
      console.log('点击了节点', nodeData)
      onNodeClick?.(nodeData)
    })

    // 绑定节点悬停事件，实现涟漪效果
    graph.on('node:mouseenter', (e: any) => {
      graph?.setElementState(e.itemId, 'hover', true)
    })

    graph.on('node:mouseleave', (e: any) => {
      graph?.setElementState(e.itemId, 'hover', false)
    })

    // 渲染完成后放大2倍并居中
    graph.on(GraphEvent.AFTER_LAYOUT, () => {
      if (graph) {
        let timer: any = setTimeout(async () => {
          clearTimeout(timer)
          timer = null
          await graph?.focusElement(centerNodeId)
          // 调用onRendered回调通知渲染完成
          onRendered && onRendered()
        }, 0)
      }
    })

    graph.render()
  }

  return {
    graphContainer
  }
}
